package cs304.p3.library.view;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;

import com.google.common.collect.Lists;

import cs304.p3.library.controller.BorrowerController;
import cs304.p3.library.domain.Book;
import cs304.p3.library.domain.Borrower;
import cs304.p3.library.framework.IoC;
import cs304.p3.library.framework.ViewResolver;
import cs304.p3.library.model.BorrowerLoginForm;
import cs304.p3.library.model.BorrowerSearchForm;
import cs304.p3.library.util.FixedSizeNumberDocument;

@SuppressWarnings("serial")
public class BorrowerDialog extends JDialog{
	
	private MainFrame parent;
	private JTabbedPane tabbedPane;
	private JPanel searchRootPanel, searchPanel, checkPanel, holdRootPanel, holdLoginPanel, holdControlRootPanel, finePanel;
	private BorrowerController borrowerController;
	private JTextField searchTitleField, searchAuthorField, searchSubjectField, checkBidField, holdBidField, holdCallField, fineField;
	private JPasswordField checkPasswordField, holdPasswordField;
	private JList resultList, holdlist;

	public BorrowerDialog(MainFrame frame, String title) {
		super(frame, title);
		parent = frame;
		setLayout(new BorderLayout());
		tabbedPane = new JTabbedPane();
		
		//Setup controllers and forms
		borrowerController = IoC.resolve(BorrowerController.class);
				
		//Construct the tabs and their panels
		GridBagLayout gb = new GridBagLayout();
		GridBagConstraints c = new GridBagConstraints();
		
		searchRootPanel = new JPanel();
		searchRootPanel.setLayout(new BorderLayout());
		searchPanel = new JPanel();
		searchPanel.setLayout(gb);
		searchPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		JLabel searchTitleLabel, searchAuthorLabel, searchSubjectLabel;
		searchTitleLabel = new JLabel("Title: ");
		searchAuthorLabel = new JLabel("Author: ");
		searchSubjectLabel = new JLabel("Subject: ");
		searchTitleField = new JTextField(16);
		searchAuthorField = new JTextField(16);
		searchSubjectField = new JTextField(16);
		//Title
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(searchTitleLabel, c);
		searchPanel.add(searchTitleLabel);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		gb.setConstraints(searchTitleField, c);
		searchPanel.add(searchTitleField);
		//Author
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(searchAuthorLabel, c);
		searchPanel.add(searchAuthorLabel);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		gb.setConstraints(searchAuthorField, c);
		searchPanel.add(searchAuthorField);
		//Subject
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(searchSubjectLabel, c);
		searchPanel.add(searchSubjectLabel);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		gb.setConstraints(searchSubjectField, c);
		searchPanel.add(searchSubjectField);
		//Search Button
		JButton searchButton = new JButton("Search");
		searchButton.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {
				BorrowerSearchForm form = borrowerController.getBorrowerSearchForm();
				form.setTitle(searchTitleField.getText());
				form.setAuthor(searchAuthorField.getText());
				form.setSubject(searchSubjectField.getText());
				borrowerController.performSearchAction();
				List<Book> results = form.getResults();
				
				DefaultListModel model = (DefaultListModel) resultList.getModel();
				model.clear();
				for(Book book : results) model.addElement(book.toString());
				IoC.displayCompleteMessage("Search Completed!");
			}
			
		});
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(20, 20, 10, 10);
		gb.setConstraints(searchButton, c);
		searchPanel.add(searchButton);
		searchRootPanel.add(searchPanel, BorderLayout.WEST);
		//Setup List
		resultList = new JList(new DefaultListModel());
		resultList.setPrototypeCellValue("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
		searchRootPanel.add(new JScrollPane(resultList), BorderLayout.CENTER);
		
		
		gb = new GridBagLayout();
		c = new GridBagConstraints();
		checkPanel = new JPanel();
		checkPanel.setLayout(gb);
		checkPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		JLabel checkBidLabel, checkPasswordLabel;
		checkBidLabel = new JLabel("BID: ");
		checkPasswordLabel = new JLabel("Password: ");
		checkBidField = new JTextField(8);
		checkBidField.setDocument(new FixedSizeNumberDocument(checkBidField,10));
		checkPasswordField = new JPasswordField(8);
		checkPasswordField.setEchoChar('*');
		//BID
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(checkBidLabel, c);
		checkPanel.add(checkBidLabel);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		gb.setConstraints(checkBidField, c);
		checkPanel.add(checkBidField);
		//Password
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(checkPasswordLabel, c);
		checkPanel.add(checkPasswordLabel);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		gb.setConstraints(checkPasswordField, c);
		checkPanel.add(checkPasswordField);
		//Login Button
		JButton loginButton = new JButton("Login");
		loginButton.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {
				if(checkBidField.getText().isEmpty()){
					IoC.displayUserInvalidInputMessage("BID cannot be empty!");
				}else if(checkPasswordField.getPassword().length == 0){
					IoC.displayUserInvalidInputMessage("Missing password!");
				}else{
					BorrowerLoginForm form = borrowerController.getBorrowerLoginForm();
					form.setBid(checkBidField.getText());
					form.setPassword(new String(checkPasswordField.getPassword()));
					borrowerController.performLoginAction();
					Borrower b = borrowerController.getBorrower();
					if(b != null){
						checkBidField.setText("");
						checkPasswordField.setText("");
						ViewResolver.gotoBorrowerAccountView(b);
					}
				}
			}
			
		});
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(20, 20, 10, 10);
		gb.setConstraints(loginButton, c);
		checkPanel.add(loginButton);
		
		
		
		holdRootPanel = new JPanel();
		holdRootPanel.setLayout(new BorderLayout());
		gb = new GridBagLayout();
		c = new GridBagConstraints();
		holdLoginPanel = new JPanel();
		holdLoginPanel.setLayout(gb);
		holdLoginPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		JLabel holdBidLabel, holdPasswordLabel;
		holdBidLabel = new JLabel("BID: ");
		holdPasswordLabel = new JLabel("Password: ");
		holdBidField = new JTextField(8);
		holdBidField.setDocument(new FixedSizeNumberDocument(holdBidField, 8));
		holdPasswordField = new JPasswordField(8);
		//BID
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(holdBidLabel, c);
		holdLoginPanel.add(holdBidLabel);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		gb.setConstraints(holdBidField, c);
		holdLoginPanel.add(holdBidField);
		//Password
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(holdPasswordLabel, c);
		holdLoginPanel.add(holdPasswordLabel);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		gb.setConstraints(holdPasswordField, c);
		holdLoginPanel.add(holdPasswordField);
		JButton holdLoginButotn = new JButton("Login");
		holdLoginButotn.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {
				if(holdBidField.getText().isEmpty()){
					IoC.displayUserInvalidInputMessage("BID cannot be empty!");
				}else if(holdPasswordField.getPassword().length == 0){
					IoC.displayUserInvalidInputMessage("Missing password!");
				}else{
					BorrowerLoginForm form = borrowerController.getBorrowerLoginForm();
					form.setBid(holdBidField.getText());
					form.setPassword(new String(holdPasswordField.getPassword()));
					borrowerController.performLoginAction();
					Borrower b = borrowerController.getBorrower();
					if(b != null){
						holdBidField.setText("");
						holdPasswordField.setText("");
						holdRootPanel.remove(holdLoginPanel);
						holdRootPanel.add(holdControlRootPanel, BorderLayout.CENTER);
						BorrowerDialog.this.pack();
					}
				}
			}
			
		});
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(20, 20, 10, 10);
		gb.setConstraints(holdLoginButotn, c);
		holdLoginPanel.add(holdLoginButotn);
		//Put Login panel first
		holdRootPanel.add(holdLoginPanel, BorderLayout.CENTER);
		
		//Login control panel
		holdControlRootPanel = new JPanel();
		holdControlRootPanel.setLayout(new BorderLayout());
		holdlist = new JList(new DefaultListModel());
		holdlist.setPrototypeCellValue("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
		holdControlRootPanel.add(new JScrollPane(holdlist), BorderLayout.CENTER);
		//Side panels
		JPanel holdControlPanel, exitPanel;
		exitPanel = new JPanel();
		JButton logoutButton = new JButton("Logout");
		logoutButton.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {
				holdRootPanel.remove(holdControlRootPanel);
				holdRootPanel.add(holdLoginPanel, BorderLayout.CENTER);
				DefaultListModel model = (DefaultListModel)holdlist.getModel();
				if(model.size() > 0) IoC.displayCompleteMessage("Please click \"Done\" to commit your hold requests");
				else{
					IoC.displayCompleteMessage("Good Bye!");
					BorrowerDialog.this.pack();
				}
			}
			
		});
		exitPanel.add(logoutButton);
		holdControlRootPanel.add(exitPanel, BorderLayout.SOUTH);
		//Add Hold reqeust panel
		holdControlPanel = new JPanel();
		gb = new GridBagLayout();
		c = new GridBagConstraints();
		holdControlPanel.setLayout(gb);
		holdControlPanel.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
		holdControlRootPanel.add(holdControlPanel, BorderLayout.WEST);
		JLabel holdCallLabel = new JLabel("Call Number: ");
		holdCallField = new JTextField(8);
		holdCallField.setDocument(new FixedSizeNumberDocument(holdCallField, 8));
		//Call number
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(holdCallLabel, c);
		holdControlPanel.add(holdCallLabel);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		gb.setConstraints(holdCallField, c);
		holdControlPanel.add(holdCallField);
		//Add buttons
		JButton addHold, removeHold, doneHold;
		//Add button
		addHold = new JButton("Hold");
		addHold.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {
				if(holdCallField.getText().isEmpty()) IoC.displayUserInvalidInputMessage("Call Number cannot be empty");
				else{
					DefaultListModel model = (DefaultListModel) holdlist.getModel();
					model.addElement(holdCallField.getText());
					holdCallField.setText("");
				}
			}
			
		});
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(20, 20, 10, 10);
		gb.setConstraints(addHold, c);
		holdControlPanel.add(addHold);
		//Remove button
		removeHold = new JButton("Remove");
		removeHold.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {
				DefaultListModel model = (DefaultListModel) holdlist.getModel();
				int index = holdlist.getSelectedIndex();
				if(index > -1) model.remove(index);
			}
			
		});
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(20, 20, 10, 10);
		gb.setConstraints(removeHold, c);
		holdControlPanel.add(removeHold);
		//Done button
		doneHold = new JButton("Done");
		doneHold.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {
				DefaultListModel model = (DefaultListModel) holdlist.getModel();
				int size = model.getSize();
				List<String> holds = Lists.newArrayList();
				for(int i=0; i<size; i++) holds.add((String)model.get(i));
				borrowerController.getBorrower().setHoldRequestStrings(holds);
				borrowerController.performHoldRequestAction();
				model.clear();
				parent.updateDBTables();
			}
			
		});
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(20, 20, 10, 10);
		gb.setConstraints(doneHold, c);
		holdControlPanel.add(doneHold);
		
		
		
		gb = new GridBagLayout();
		c = new GridBagConstraints();
		finePanel = new JPanel();
		finePanel.setLayout(gb);
		finePanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		JLabel fineLabel = new JLabel("FID: ");
		fineField = new JTextField(8);
		fineField.setDocument(new FixedSizeNumberDocument(fineField, 8));
		//Fine
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(10, 15, 5, 0);
		gb.setConstraints(fineLabel, c);
		finePanel.add(fineLabel);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 5, 10);
		gb.setConstraints(fineField, c);
		finePanel.add(fineField);
		JButton payButton = new JButton("Pay");
		payButton.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {
				String fid = fineField.getText();
				if(fid.isEmpty()) IoC.displayUserInvalidInputMessage("FID cannot be empty");
				else{
					borrowerController.getBorrower().setFid(fid);
					borrowerController.performPayFineAction();
				}
			}
			
		});
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(20, 20, 10, 10);
		gb.setConstraints(payButton, c);
		finePanel.add(payButton);
		
		
		
		tabbedPane.add(searchRootPanel, "Search");
		tabbedPane.add(checkPanel, "Account");
		tabbedPane.add(holdRootPanel, "Hold Requests");
		tabbedPane.add(finePanel, "Pay Fine");
		
		JPanel buttonPanel = new JPanel();
		JButton exitButton = new JButton("Close");
		exitButton.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {
				BorrowerDialog.this.setVisible(false);
				BorrowerDialog.this.dispose();
			}
			
		});
		buttonPanel.add(exitButton);
		add(buttonPanel, BorderLayout.SOUTH);
		
		//finalize and show
		add(tabbedPane, BorderLayout.CENTER);
		pack();
		setResizable(false);
		Point loc = frame.getLocationOnScreen();
		Dimension d = frame.getSize();
		setLocation(loc.x + (d.width - getWidth())/2, loc.y + (d.height - getHeight())/2);
	  	setDefaultCloseOperation(DISPOSE_ON_CLOSE);
	    setVisible(true);
	}

}
